package com.jebel.framwork.common.util;

import io.vertx.core.json.JsonObject;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * @author linmingxi
 * 2019/04/29
 */
@Component
public class CipherCodeToken {

    private static String IV = "AB012CDEF3456789";//偏移量字符串必须是16位 当模式是CBC的时候必须设置偏移量
    private static String KEY = "ABCD123Ef4567890DEF123456789ABC0";//hexStringToBytes("0123456789ABCDEF");

    private static String ALGORITHM = "AES";
    private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; //算法/模式/补码方式

    public static byte[] AES_CBC_Decrypt(byte[] data) throws Exception{
        Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
        return cipher.doFinal(data);
    }

    public static byte[] AES_CBC_ecrypt(byte[] data) throws Exception{
        Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
        return cipher.doFinal(data);
    }

    private static Cipher getCipher(int mode) throws Exception{
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        //因为AES的加密块大小是128bit(16byte), 所以key是128、192、256bit无关
        SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        cipher.init(mode, secretKeySpec, new IvParameterSpec(IV.getBytes()));
        return cipher;
    }

    @Value("${CODE_IV}")
    public void setIV(String IV) {
        if (StringUtil.isEmpty(IV)){
            IV = "0123456789ABCDEF";
        }
        CipherCodeToken.IV = IV;
    }

    @Value("${CODE_KEY}")
    public void setKEY(String KEY) {
        if (StringUtil.isEmpty(KEY)){
            KEY = "1234567890ABCDEF1234567890ABCDEf";
        }
        CipherCodeToken.KEY = KEY;
    }

    /**
     * 加密16进制
     * @param data
     * @return
     */
    public static String encode(String data){
        String dataBytes = null;
        try {
            byte[] bytes = AES_CBC_ecrypt(data.getBytes());
            dataBytes = Hex.encodeHexString(bytes);
            return dataBytes;//new String(AES_CBC_Decrypt());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密16进制
     * @param data
     * @return
     */
    public static String deCode(String data){
        byte[] dataBytes = null;
        try {
            dataBytes = Hex.decodeHex(data.toCharArray());
            return new String(AES_CBC_Decrypt(dataBytes));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
/*    public static void main(String[] args) {
        String crypto = "c1723326200740b5951047c0fa044550";
        String base64Str = Base64.encodeBase64String(crypto.getBytes());
        byte[] bytes = Base64.decodeBase64(base64Str.getBytes());
        byte[] bytes2 = Base64.decodeBase64("wXIzJiAHQLWVEEfA+gRFUA==".getBytes());
        System.out.println(new String(bytes));
        System.out.println(new String(bytes2));
        System.out.println(base64Str);
        System.out.println(deCode(crypto));
    }*/

    //测试
    public static void main(String args[]) {

        JsonObject jsonObject = new JsonObject();
        jsonObject.put("channel","weixin");
        jsonObject.put("orderCode","AsBCCC111111111");
        jsonObject.put("payFee","11111111");
        jsonObject.put("createTime",DateUtil.parseDate2Forat(new Date(),DateUtil.DEFAULT_PATTERN));

         String encode = encode(jsonObject.toString());
        System.out.println(encode);
        System.out.println("wx11111:"+encode("wx11111"));
        System.out.println(deCode(encode));
        //System.out.println(deCode(encode));
       // System.out.println(deCode("7b9d2e45e42a2478c096127698f37a9c7e6b5378b5b97ca3f49eead516d26b80"));
    }
}
